!(function () {
  class IMap {
    constructor(opt) {
      this._init(opt)
    }

    _init(opt) {
      let id = opt.id || 'mapid';
      let center = opt.center || [30.19637640408235, 120.18273066611019]
      let zoom = opt.zoom || 13;
      let tileLayerUrl = opt.tileLayerUrl || 'https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png'
      let click = opt.click
      this.map = L.map(id, {
        zoomControl: false,
        attributionControl: false
      });
      this.setCenterAndZoom(center, zoom);
      this.tileLayer = L.tileLayer(tileLayerUrl, {})
      this.tileLayer.addTo(this.map);

      this.map.on('click', function (e) {
        typeof click === 'function' && click(e)
      })
    }

    getMap() {
      return this.map;
    }

    getZoom() {
      return this.map.getZoom();
    }

    addOverlay(marker) {
      marker.addTo(this.map)
    }

    removeOverlay(marker) {
      marker.remove()
    }

    setCenterAndZoom(center, zoom) {
      this.map.setView(center, zoom)
    }

    resizeContainer() {
      this.map.invalidateSize();
    }

    createPoint(obj) {
      var icon = this.createIcon(obj.imageUrl, {
        iconSize: [obj.width, obj.height],
        iconAnchor: [obj.width / 2, obj.height / 2],
      })
      var opt = {
        icon: icon
      }
      var marker = this.createMarker([obj.latitude, obj.longitude], opt)
      marker._data = obj;

      if (typeof obj.click === 'function') {
        marker.on('click', obj.click)
      }

      return marker;
    }

    createMarker(latLng, opt) {
      let marker = L.marker(latLng, opt)
      return marker;
    }

    addMarker(latLng, opt = {}) {
      let opts = {}
      if (opt.url) opts.icon = this.createIcon(opt.url)
      if (opt.icon) opts.icon = opt.icon
      let marker = L.marker(latLng, opts);
      marker.addTo(this.map);
      if (typeof opt.click === 'function') {
        marker.on('click', opt.click)
      }

      return marker;
    }

    createIcon(url, opt) {
      let opts = Object.assign({
        iconUrl: url
      }, opt)
      return L.icon(opts);
    }
  }

  window.Map = IMap;

})();